package com.engine
{
	import away3d.cameras.Camera3D;
	import away3d.containers.ObjectContainer3D;
	import away3d.containers.View3D;
	import away3d.controllers.HoverController;
	import away3d.debug.AwayStats;
	import away3d.lights.LightBase;
	import away3d.materials.lightpickers.StaticLightPicker;
	import away3d.textures.PlanarReflectionTexture;
	
	import com.greensock.TweenLite;
	
	import flash.display.Stage;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;

	public class AwayEngine
	{
		private static var reflect:PlanarReflectionTexture;
		public static function addReflect(r:PlanarReflectionTexture):void{
			reflect = r;
		}
		
		public static function get senceHeight():int
		{
			return nativeStage.stageHeight;
		}
		public static function get senceWidth():int
		{
			return nativeStage.stageWidth;
		}
		
		private static var _view3D:View3D;

		public static function get view3D():View3D
		{
			return _view3D;
		}
		
		public static function get camera():Camera3D{
			return _view3D.camera;
		}

		public static function addMesh(obj:ObjectContainer3D):void{
			_view3D.scene.addChild(obj);
		}
		
		public static function removeMesh(obj:ObjectContainer3D):void{
			if(obj.parent != null){
				obj.parent.removeChild(obj);
			}
		}
		
		private static var _lightPicker:StaticLightPicker;
		public static function get lightPicker():StaticLightPicker
		{
			if(_lightPicker == null)createPicker();
			return _lightPicker;
		}

		private static var lightList:Array;
		public static function addLight(light:LightBase):void{
			if(_lightPicker == null)createPicker();
			lightList.push(light);
			addMesh(light);
			_lightPicker.lights = lightList;
		}
		
		public static function removeLight(light:LightBase):void{
			if(lightList == null)return;
			var index:int = lightList.indexOf(light);
			if(index >= 0){
				lightList.splice(index,1);
				_lightPicker.lights = lightList;
				removeMesh(light);
			}
		}
		
		private static function createPicker():void{
			lightList = [];
			_lightPicker = new StaticLightPicker(lightList);
		}
		
		private static var cameraController:HoverController;//360全景展示相机控制器
		private static var nativeStage:flash.display.Stage;
//		private static var starlingStage:starling.display.Stage;
		
		private static var lastPanAngle:Number;
		private static var lastTiltAngle:Number;
		private static var lastMouseX:Number;
		private static var lastMouseY:Number;
		private static var move:Boolean;
		
		public static function createView(s:flash.display.Stage,/*ss:starling.display.Stage,*/
										  anti:int = 4,canUpdate:Boolean = true):View3D
		{
			nativeStage = s;
//			starlingStage = ss;
			initView(anti);
			cameraEnabled = true;
			if(canUpdate)s.addEventListener(Event.ENTER_FRAME, onUpdate);
			nativeStage.scaleMode = StageScaleMode.NO_SCALE;
			nativeStage.align = StageAlign.TOP_LEFT;
			return _view3D;
		}
		
		private static var _cameraEnabled:Boolean;
		public static function set cameraEnabled(value:Boolean):void{
			_cameraEnabled = value;
			if(value){
//				starlingStage.addEventListener(TouchEvent.TOUCH,stageTouch);
				nativeStage.addEventListener(MouseEvent.MOUSE_WHEEL,onWheel);
				nativeStage.addEventListener(MouseEvent.MOUSE_DOWN,stageTouch);
				nativeStage.addEventListener(MouseEvent.MOUSE_UP,stageTouch);
				nativeStage.addEventListener(Event.MOUSE_LEAVE,stageTouch);
				nativeStage.addEventListener(Event.RESIZE, onResize);
			}else{
//				starlingStage.removeEventListener(TouchEvent.TOUCH,stageTouch);
				nativeStage.removeEventListener(MouseEvent.MOUSE_WHEEL,onWheel);
				nativeStage.removeEventListener(MouseEvent.MOUSE_DOWN,stageTouch);
				nativeStage.removeEventListener(MouseEvent.MOUSE_UP,stageTouch);
				nativeStage.removeEventListener(Event.MOUSE_LEAVE,stageTouch);
				nativeStage.removeEventListener(Event.RESIZE, onResize);
				onMouseUp();
			}
		}
		
		public static function stageTouch(e:Event):void
		{
//			var touch:Touch = e.getTouch(starlingStage);
//			if(touch)
//			{
				switch(e.type/*touch.phase*/)
				{
					case MouseEvent.MOUSE_DOWN:
						onMouseDown();
						break;
					case Event.MOUSE_LEAVE:
					case MouseEvent.MOUSE_UP:
						onMouseUp();
						break;
				}
//			}
		}
		
		public static function addResize(func:Function):void{
			nativeStage.addEventListener(Event.RESIZE, func);
		}
		public static function removeResize(func:Function):void{
			nativeStage.removeEventListener(Event.RESIZE, func);
		}
		
		/**
		 * 侦听舞台尺寸改变事件
		 */
		private static function onResize(event:Event = null):void
		{
			_view3D.width = nativeStage.stageWidth;
			_view3D.height = nativeStage.stageHeight;
			_stats.x = _stats.y = 0;
		}
		
		private static var _stats:AwayStats;//调试窗口
		public static function set showStats(value:Boolean):void{
			if(value){
				if(_stats == null)_stats = new AwayStats(_view3D);
				nativeStage.addChild(_stats);
			}else{
				if(_stats != null)nativeStage.removeChild(_stats);
			}
		}
		
		/**
		 * 鼠标按下事件
		 */
		private static function onMouseDown():void
		{
			if(cameraController == null || !_cameraEnabled)return;//不能交互
//			trace('触发触摸舞台');
			lastPanAngle = cameraController.panAngle;
			lastTiltAngle = cameraController.tiltAngle;
			lastMouseX = nativeStage.mouseX;
			lastMouseY = nativeStage.mouseY;
			move = true;
		}
		
		/**
		 * 鼠标弹起事件
		 */
		private static function onMouseUp():void
		{
			move = false;
		}
		
		private static var _perDistance:Number = 100;//放大镜移动的距离
		public static function get perDistance():Number
		{
			return _perDistance;
		}
		public static function set perDistance(value:Number):void
		{
			_perDistance = value;
		}
		
		private static function onWheel(e:MouseEvent):void
		{
			if(e.delta > 0){
				zoomCamera(false);
			}else{
				zoomCamera(true);
			}
		}
		/**
		 * 让相机临时停止旋转
		 */		
		public static function stopCamera():void{
			move = false;
		}
		
		public static function zoomCamera(isLarge:Boolean = false):void{
			if(isLarge){
				if(cameraController.distance > minDistance)
					TweenLite.to(cameraController,.5,
						{distance:cameraController.distance - _perDistance});
			}else{
				if(cameraController.distance < maxDistance)
					TweenLite.to(cameraController,.5,
						{distance:cameraController.distance + _perDistance});
			}
		}
		
		private static function initView(anti:int):void
		{
			if(_view3D == null)_view3D = new View3D();
			_view3D.antiAlias = anti;
			_view3D.backgroundColor = 0;
			_view3D.backgroundAlpha = 0;
		}
		
		private static function initCamera(camera:Camera3D):void
		{
			if(cameraController == null)
				cameraController = new HoverController(camera);
		}
		
		private static var minDistance:Number;
		private static var maxDistance:Number;
		public static function setCamera(minDis:Number,maxDis:Number,
				minTiltAngle:Number = 0,maxTiltAngle:Number = 90,
				panAngle:Number = 45,tiltAngle:Number = 20):void{
			minDistance = minDis;
			maxDistance = maxDis;
			initCamera(_view3D.camera);
			cameraController.distance = (maxDis + minDis) / 2;//摄像机和目标点距离
			cameraController.minTiltAngle = minTiltAngle;//摄像机以Y轴旋转最小角度
			cameraController.maxTiltAngle = maxTiltAngle;//摄像机以Y轴旋转最大角度
			cameraController.panAngle = panAngle;//摄像机以Y轴旋转角度
			cameraController.tiltAngle = tiltAngle;//摄像机以X轴旋转角度
		}
		
		public static function onUpdate(event:Event = null):void
		{
			// 渲染3D世界
			if (move) {
				cameraController.panAngle = 0.3 * (nativeStage.mouseX - lastMouseX) + lastPanAngle;
				cameraController.tiltAngle = 0.3 * (nativeStage.mouseY - lastMouseY) + lastTiltAngle;
			}
			if(reflect != null){
				if(cameraController != null)cameraController.update();
				reflect.render(_view3D);
			}
			_view3D.render();
		}
		
		public static function addLoop(handler:Function):void{
			nativeStage.addEventListener(Event.ENTER_FRAME,handler);
		}
		public static function removeLoop(handler:Function):void{
			nativeStage.removeEventListener(Event.ENTER_FRAME,handler);
		}
		public static function control(handler:Function):void{
			nativeStage.addEventListener(MouseEvent.CLICK,handler);
		}
		
		
	}
}